package com.danbay.framework.db.datasource;

import com.alibaba.druid.pool.DruidDataSource;
import com.danbay.framework.db.datasource.aspect.DataSourceAspect;
import com.danbay.framework.db.datasource.druid.*;
import com.danbay.framework.utils.StringUtils;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author SJG
 * @date 2017/10/17
 * Druid的DataResource配置类
 */
@EnableTransactionManagement
@ConditionalOnProperty(name = "druid-disable", havingValue = "false", matchIfMissing = true)
@EnableConfigurationProperties({DruidStatProperties.class,})
@Import({DruidSpringAopConfiguration.class, DruidStatViewServletConfiguration.class, DruidWebStatFilterConfiguration.class, DruidFilterConfiguration.class})
public class DruidDynamicDataSourceConfig {

    private DynamicDataSourceProperties dynamicDataSourceProperties;
    private static String defaultDatasourceName;

    @Bean
    @Primary
    public DynamicDataSourceProperties getDynamicDataSourceProperties() {
        return new DynamicDataSourceProperties();
    }

    @Primary
    @Bean
    public DataSource dataSource(DynamicDataSourceProperties dynamicDataSourceProperties) {
        this.dynamicDataSourceProperties = dynamicDataSourceProperties;
        DynamicDataSourceProperties.DruidDataSourceActives dataSourceActives = dynamicDataSourceProperties.getDruid().getActives();
        List<DataSourceProperties> allDataSources = new ArrayList<>();
        allDataSources.add(dataSourceActives.getOne());
        allDataSources.add(dataSourceActives.getTwo());
        allDataSources.add(dataSourceActives.getThree());
        allDataSources.add(dataSourceActives.getFour());
        allDataSources.add(dataSourceActives.getFive());
        allDataSources.add(dataSourceActives.getSix());
        allDataSources.add(dataSourceActives.getSeven());
        allDataSources.add(dataSourceActives.getEight());
        allDataSources.add(dataSourceActives.getNine());
        allDataSources.add(dataSourceActives.getTen());
        DataSource defaultDataSource = null;
        Map<String, DataSource> dataSourceMap = new HashMap<>(2);
        for (int i = 0; i < allDataSources.size(); i++) {
            DataSourceProperties dataSourceProperties = allDataSources.get(i);
            if (dataSourceProperties != null) {
                DruidDataSource dataSource = createDruidDataSource(dataSourceProperties);
                String name = DataSourceEnum.fromValue(i + 1).name().toLowerCase();
                dataSource.setName(name);
                dataSourceMap.put(name, dataSource);
                if (defaultDataSource == null) {
                    defaultDataSource = dataSource;
                    defaultDatasourceName = name;
                }
            }
        }
        if (dataSourceMap.size() < 1) {
            throw new IllegalArgumentException("至少需要一个可用的数据源配置");
        }
        DynamicDataSource dynamicDataSource = new DynamicDataSource(defaultDataSource, dataSourceMap);
        return dynamicDataSource;
    }

    @Bean
    public DataSourceAspect getDataSourceAspect() {
        return new DataSourceAspect();
    }

    /**
     * 生成druid数据源
     *
     * @param dataSourceProperties 数据源配置
     * @return 数据源
     */
    public DruidDataSource createDruidDataSource(DataSourceProperties dataSourceProperties) {
        DynamicDataSourceProperties.DruidConfig druidConfig = dynamicDataSourceProperties.getDruid();
        DruidDataSource datasource = new DruidDataSource();
        //继承默认配置
        datasource.setDriverClassName(dynamicDataSourceProperties.getDriverClassName());
        datasource.setUsername(dynamicDataSourceProperties.getUsername());
        datasource.setPassword(dynamicDataSourceProperties.getPassword());
        datasource.setUrl(dynamicDataSourceProperties.getUrl());
        //druid配置
        datasource.setInitialSize(druidConfig.getInitialSize());
        datasource.setMinIdle(druidConfig.getMinIdle());
        datasource.setMaxWait(druidConfig.getMaxWait());
        datasource.setMaxActive(druidConfig.getMaxActive());
        datasource.setMinEvictableIdleTimeMillis(druidConfig.getMinEvictableIdleTimeMillis());
        try {
            datasource.setFilters(druidConfig.getFilters());
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //覆盖默认配置
        String driverClassName = dataSourceProperties.getDriverClassName();
        if (StringUtils.isNotBlank(driverClassName)) {
            datasource.setDriverClassName(driverClassName);
        }
        String url = dataSourceProperties.getUrl();
        if (StringUtils.isNotBlank(url)) {
            datasource.setUrl(url);
        }
        String userName = dataSourceProperties.getUsername();
        if (StringUtils.isNotBlank(userName)) {
            datasource.setUsername(userName);
        }
        String password = dataSourceProperties.getPassword();
        if (StringUtils.isNotBlank(password)) {
            datasource.setPassword(password);
        }
        return datasource;
    }

    public static String getDefaultDatasourceName() {
        return defaultDatasourceName;
    }
}